using System;
using System.ServiceModel;
using System.ServiceModel.Channels;

namespace WcfExtensions.ServiceModel.Channels
{
    internal class CompressionRequestChannel<TChannelShape> : CompressionChannel<TChannelShape>, IRequestChannel
        where TChannelShape : class, IRequestChannel
    {
        internal CompressionRequestChannel(ChannelManagerBase channelManagerBase, TChannelShape innerChannel)
            : base(channelManagerBase, innerChannel)
        {
        }

        #region IRequestChannel Members

        public IAsyncResult BeginRequest(Message message, TimeSpan timeout, AsyncCallback callback, object state)
        {
            return InnerChannel.BeginRequest(Compressor.CompressMessage(message), timeout, callback, state);
        }

        public IAsyncResult BeginRequest(Message message, AsyncCallback callback, object state)
        {
            return InnerChannel.BeginRequest(Compressor.CompressMessage(message), callback, state);
        }

        public Message EndRequest(IAsyncResult result)
        {
            Message reply = InnerChannel.EndRequest(result);
            return reply == null ? reply : MessageCompressor.DecompressMessage(reply);
        }

        public EndpointAddress RemoteAddress
        {
            get { return InnerChannel.RemoteAddress; }
        }

        public Message Request(Message message, TimeSpan timeout)
        {
            Message compressedMessage = Compressor.CompressMessage(message);
            Message reply = InnerChannel.Request(compressedMessage, timeout);
            return reply == null ? reply : MessageCompressor.DecompressMessage(reply);
        }

        public Message Request(Message message)
        {
            Message compressedMessage = Compressor.CompressMessage(message);
            Message reply = InnerChannel.Request(compressedMessage);
            return reply == null ? reply : MessageCompressor.DecompressMessage(reply);
        }

        public Uri Via
        {
            get { return InnerChannel.Via; }
        }

        #endregion
    }
}